import type { SourceType, XYCoord } from '../classes/interface';
export interface DragSourceMonitor<DragItem = unknown, DropResult = unknown> {
  receiveHandlerId: (handlerId: string) => void;
  subscribeStateChange: (listenerFn: () => void) => void;
  isDragging: () => boolean;
  getDragStartNodeClientOffset: () => XYCoord | undefined;
  getDragStartEventClientOffset: () => XYCoord | undefined;
  getItem: () => DragItem;
  getDropResult: () => DropResult | undefined;
}

export type FactoryOrInstance<T> = T | (() => T);
export type DragObjectFactory<T> = (monitor: DragSourceMonitor<T>) => T | null;

export interface DragSourceHookSpec<DragItem, DropResult, CollectedProps> {
  type: SourceType;
  dragNode: HTMLElement | null;
  item?: DragItem;
  end?: (
    draggedItem: DragItem,
    monitor: DragSourceMonitor<DragItem, DropResult>,
  ) => void;
  canDrag?:
    | boolean
    | ((monitor: DragSourceMonitor<DragItem, DropResult>) => boolean);
  // isDragging?: (monitor: DragSourceMonitor<DragItem, DropResult>) => boolean;
  collect?: (
    monitor: DragSourceMonitor<DragItem, DropResult>,
  ) => CollectedProps;
}

export interface DragSource {
  getItem: () => any;
  setSpec: (newSpec: any) => void;
  canDrag: () => boolean;
  getDragNode: () => HTMLElement | null;
  endDrag: () => void;
}
